﻿package org.hsl.haxe;
import org.hsl.haxe.ISlot;
/**
 * The slot list contains all the slots that will be used to notify the listeners.
 */
interface ISlotList<D> {
	/**
	 * Indicates whether the slot list has any slots in it.
	 * 
	 * This property can be used for speed optimizations. If a slot list has no slots, the dispatcher that owns that slot list
	 * does not have to calculate a value that will only be used to be sent in a signal.
	 */
	public var hasSlots(getHasSlots, null):Bool;
	/**
	 * Adds a method that accepts nothing, and returns nothing, as a slot and returns that slot. The slot can be removed by
	 * calling the destroyNiladic method of the slot list, or the destroy method of the slot.
	 * 
	 * Using niladic slots, you cannot access the data sent in the signals. If you need that data, use the createRegular method
	 * or the createSimple method. The former is more advanced than the latter.
	 */
	public function addNiladic(method:Void -> Void):ISlot<D>;
	/**
	 * Adds a method that accepts a signal, and returns nothing, as a slot and returns that slot. The slot can be removed by
	 * calling the destroyRegular method of the slot list, or the destroy method of the slot.
	 * 
	 * In a lot of cases, there is no need to accept the entire signal. For those cases, you could use the createNiladic method
	 * or the createSimple method instead.
	 */
	public function addRegular(method:Signal<D> -> Void):ISlot<D>;
	/**
	 * Adds a method that accepts data of the type that equals the type parameter of this slot list, and returns nothing, as a
	 * slot and returns that slot. The slot can be removed by calling the destroySimple method of the slot list, or the destroy
	 * method of the slot.
	 */
	public function addSimple(method:D -> Void):ISlot<D>;
	private function getHasSlots():Bool;
	/**
	 * Removes a slot added by the createNiladic method. Returns true if the removal succeeded; false if this slot list does not
	 * have the passed method registered as a niladic slot.
	 */
	public function removeNiladic(method:Void -> Void):Bool;
	/**
	 * Removes a slot added by the createRegular method. Returns true if the removal succeeded; false if this slot list does not
	 * have the passed method registered as a regular slot.
	 */
	public function removeRegular(method:Signal<D> -> Void):Bool;
	/**
	 * Removes a slot added by the createSimple method. Returns true if the removal succeeded; false if this slot list does not
	 * have the passed method registered as a simple slot.
	 */
	public function removeSimple(method:D -> Void):Bool;
}
/**
 * A null object implementation of the ISlotList interface.
 */
class NullSlotList<D> implements ISlotList<D> {
	public var hasSlots(getHasSlots, null):Bool;
	/**
	 * Creates a new null slot list.
	 */
	public function new():Void {
	}
	public function addNiladic(method:Void -> Void):ISlot<D> {
		return new NullSlot<D>();
	}
	public function addRegular(method:Signal<D> -> Void):ISlot<D> {
		return new NullSlot<D>();
	}
	public function addSimple(method:D -> Void):ISlot<D> {
		return new NullSlot<D>();
	}
	public function getHasSlots():Bool {
		return false;
	}
	public function removeNiladic(method:Void -> Void):Bool {
		return false;
	}
	public function removeRegular(method:Signal<D> -> Void):Bool {
		return false;
	}
	public function removeSimple(method:D -> Void):Bool {
		return false;
	}
	private function toString():String {
		return "[ISlotList]";
	}
}